/***************************************************************************
 * 文件名：CSSolutionModel
 * 功能：
 * 说明：
 * -------------------------------------------------------------------------
 * 创建时间：2025/7/14 10:46:23
 * 创建人：葛浩
 * 邮箱： 2094733071@qq.com
 * =========================================================================
 *
 * 修改人：   
 * 修改时间：   
 * 修改说明：   
 ***************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace BuiltInTools
{
	/// <summary>
	///解决方案模型类
	/// </summary>
	public class CSSolutionModel
	{
		/// <summary>
		/// 名称
		/// </summary>
		public string FileName { get; set; }

		/// <summary>
		/// 项目
		/// </summary>
		public List<CSProjectModel> Projects { get; set; }

		/// <summary>
		/// 选中的项目
		/// </summary>
		public List<CSProjectModel> SelectedProjects { get; private set; }

		/// <summary>
		/// 程序集引用列表
		/// </summary>
		public List<AssemblyReferenceModel> AllAssemblyReferenceList { get; set; }

		/// <summary>
		/// 项目引用列表
		/// </summary>
		public List<ProjectReferenceModel> AllProjectReferenceList { get; set; }

		/// <summary>
		/// 包引用列表
		/// </summary>
		public List<PackageReferenceModel> AllPackageReferenceList { get; set; }

		/// <summary>
		/// 所有引用
		/// </summary>
		public List<AllReferenceModel> AllReferenceList { get; set; }

		public CSSolutionModel()
		{
			this.Projects = new List<CSProjectModel>();
			this.SelectedProjects = new List<CSProjectModel>();
			this.AllAssemblyReferenceList = new List<AssemblyReferenceModel>();
			this.AllProjectReferenceList = new List<ProjectReferenceModel>();
			this.AllPackageReferenceList = new List<PackageReferenceModel>();

		}

		public CSSolutionModel(string solutionFilePath)
		{
			this.FileName = solutionFilePath;
			this.Projects = new List<CSProjectModel>();
			this.SelectedProjects = new List<CSProjectModel>();
			this.AllReferenceList = new List<AllReferenceModel>();
			this.AllAssemblyReferenceList = new List<AssemblyReferenceModel>();
			this.AllProjectReferenceList = new List<ProjectReferenceModel>();
			this.AllPackageReferenceList = new List<PackageReferenceModel>();
		}

		/// <summary>
		/// 获取解决方案模型类
		/// </summary>
		/// <param name="solutionPath"></param>
		/// <param name="selectedProjNameList"></param>
		/// <returns></returns>
		/// <exception cref="ArgumentException"></exception>
		public static CSSolutionModel GetSolution(string solutionPath, List<string> selectedProjNameList)
		{
			if (!File.Exists(solutionPath))
			{
				throw new ArgumentException($"解决方案{solutionPath}不存在！");
			}
			var solution = new CSSolutionModel(solutionPath);

			solution.Projects = CSProjectModel.LoadSolutionProjects(solution, File.ReadAllText(solution.FileName, Encoding.UTF8)).OrderBy(p => p.ProjectName).ToList();

			solution.SelectedProjects = solution.Projects.Where(p => selectedProjNameList.Any(x => x == p.ProjectName)).ToList();

			solution.Projects.ForEach(projItem =>
			{
				solution.AllReferenceList.AddRange(projItem.AllReferenceModels.OrderBy(p => p.ProjectName).ThenBy(p => p.ReferenceName).ToList());
				solution.AllAssemblyReferenceList.AddRange(projItem.AssemblyReferenceModels.OrderBy(p => p.ProjectName).ToList());
				solution.AllProjectReferenceList.AddRange(projItem.ProjectReferenceModels.OrderBy(p => p.ProjectName).ToList());
				solution.AllPackageReferenceList.AddRange(projItem.PackageReferenceModels.OrderBy(p => p.ProjectName).ToList());
			});

			solution.Projects = solution.Projects.OrderBy(p => p.ProjectName).ToList();
			return solution;
		}
	}

	/// <summary>
	/// CS项目模型类
	/// </summary>
	public class CSProjectModel
	{
		#region Properties

		/// <summary>
		/// 项目名称
		/// </summary>
		public string ProjectName { get; set; }

		/// <summary>
		/// 相对路径
		/// </summary>
		public string RelativePath { get; set; }

		/// <summary>
		/// 文件名称
		/// </summary>
		public string FileName { get; set; }

		/// <summary>
		/// 所属文件夹Guid
		/// </summary>
		public Guid FoldGuid { get; set; }

		public string ProjectGuid { get; set; }

		/// <summary>
		/// 所有引用
		/// </summary>
		public List<AllReferenceModel> AllReferenceModels { get; set; }

		/// <summary>
		/// 程序集引用列表
		/// </summary>
		public List<AssemblyReferenceModel> AssemblyReferenceModels { get; set; }

		/// <summary>
		/// 项目引用列表
		/// </summary>
		public List<ProjectReferenceModel> ProjectReferenceModels { get; set; }

		/// <summary>
		/// 包引用列表
		/// </summary>
		public List<PackageReferenceModel> PackageReferenceModels { get; set; }

		#endregion

		protected CSProjectModel()
		{
			this.AllReferenceModels = new List<AllReferenceModel>();
			this.AssemblyReferenceModels = new List<AssemblyReferenceModel>();
			this.ProjectReferenceModels = new List<ProjectReferenceModel>();
			this.PackageReferenceModels = new List<PackageReferenceModel>();
		}

		/// <summary>
		/// 创建默认的CS项目模型
		/// </summary>
		/// <param name="projName"></param>
		/// <param name="relativePath"></param>
		/// <param name="fileName"></param>
		/// <returns></returns>
		public static CSProjectModel CreateDefault(string projName, string relativePath, string fileName)
		{
			var result = new CSProjectModel();

			result.ProjectName = projName;
			result.RelativePath = relativePath;
			result.FileName = fileName;

			return result;
		}

		/// <summary>
		/// 加载解决方案项目
		/// </summary>
		/// <param name="solutionModel"></param>
		/// <param name="slnContext"></param>
		/// <returns></returns>
		public static List<CSProjectModel> LoadSolutionProjects(CSSolutionModel solutionModel, string slnContext)
		{
			var list = SolutionUtil.GetSolutionProjectList(solutionModel.FileName);
			if (list?.Count == 0)
			{
				return null;
			}

			solutionModel.Projects.AddRange(list.Where(p => p.ProjectType == "KnownToBeMSBuildFormat").Select(p => new CSProjectModel
			{
				ProjectName = p.ProjectName,
				RelativePath = p.RelativePath,
				FileName = p.FullName,
				ProjectGuid = p.ProjectGuid,
			}).ToList());

			foreach (var projItem in solutionModel.Projects)
			{
				if (!File.Exists(projItem.FileName))
				{
					continue;
				}

				//查找引用
				var refList = ReferenceEditor.Search(projItem.FileName);
				if (refList?.Count == 0)
				{
					continue;
				}

				var refItem = refList[0];
				if (refItem == null)
				{
					continue;
				}

				if (refItem.AllReferenceList?.Count > 0)
				{
					projItem.AllReferenceModels.AddRange(refItem.AllReferenceList.OrderBy(p => p.ReferenceName).ToList());
				}

				//添加程序集引用列表
				if (refItem.AssemblyList?.Count > 0)
				{
					projItem.AssemblyReferenceModels.AddRange(refItem.AssemblyList.OrderBy(p => p.AssemblyReferenceName).ToList());
				}

				//添加项目引用列表
				if (refItem.ProjectList?.Count > 0)
				{
					projItem.ProjectReferenceModels.AddRange(refItem.ProjectList.OrderBy(p => p.ProjectReferneceName).ToList());
				}

				//添加包引用列表
				if (refItem.PackageList?.Count > 0)
				{
					projItem.PackageReferenceModels.AddRange(refItem.PackageList.OrderBy(p => p.PackageReferenceName).ToList());
				}
			}

			return solutionModel.Projects;
		}
	}

	/// <summary>
	/// 项目引用项
	/// </summary>
	public class CSProjectReferenceItemModel
	{
		/// <summary>
		/// 项目名称
		/// </summary>
		public string ProjectName { get; set; }

		/// <summary>
		/// 项目文件名
		/// </summary>
		public string ProjectFileName { get; set; }

		/// <summary>
		/// 引用类型
		/// </summary>
		public string ReferenceType { get; set; }

		/// <summary>
		/// 引用名称
		/// </summary>
		public string ReferenceName { get; set; }

		/// <summary>
		/// 引用的值
		/// </summary>
		public string ReferenceValue { get; set; }
	}

	/// <summary>
	/// 引用基类
	/// </summary>
	public class ReferenceBase
	{
		/// <summary>
		/// 项目名称
		/// </summary>
		public string ProjectName { get; set; }

		/// <summary>
		/// 项目文件名
		/// </summary>
		public string ProjectFileName { get; set; }

		/// <summary>
		/// 引用名称
		/// </summary>
		public string ReferenceName { get; set; }
	}

	/// <summary>
	/// 添加引用时界面展示  程序集引用
	/// </summary>
	public class AssemblyRefModel : ReferenceBase
	{
		/// <summary>
		/// 程序集地址
		/// </summary>
		public string FileName { get; set; }
	}

	/// <summary>
	/// 添加引用时界面展示  项目引用
	/// </summary>
	public class ProjectRefModel : ReferenceBase
	{
		/// <summary>
		/// 相对地址
		/// </summary>
		public string RelativePath { get; set; }

		/// <summary>
		/// 绝对地址
		/// </summary>
		public string AbsolutePath { get; set; }
	}
}
